/*
 * ProtocoloServidor.cpp
 *
 * Author: Grupo Nro.
 */

#include "ProtocoloServidor.h"

ProtocoloServidor::ProtocoloServidor() {
}

ProtocoloServidor::~ProtocoloServidor() {
}

string ProtocoloServidor::formatearLongitud(string & longitud){
	if (longitud.length() < CANT_BYTES_TAMANIO){
		string cadena = "";
		string cero = "0";
		int faltante = CANT_BYTES_TAMANIO - longitud.length();
		int i = 0;
		while (i < faltante){
			cadena.append(cero.c_str());
			i++;
		}
		cadena.append(longitud);
		return cadena;
	}

	return longitud;
}

string ProtocoloServidor::armarPrimerMensaje(string & codigoMensaje, long longitud){
	//Me aseguro que la longitud del codigo de mensaje sea la correcta
	if (codigoMensaje.length() != CANT_BYTES_CODIGO){
		string mensajeError = "Error en el código del mensaje que se intentar usar. Código:";
		mensajeError.append(codigoMensaje.c_str());
		throw ComunicacionException(mensajeError, true);
	}

	//Verifico longitud del mensaje
	string numeroCadena = Utils::pasarLongACadena(longitud);
	if (numeroCadena.length() > CANT_BYTES_TAMANIO){
		string mensajeError = "Error - mensaje mas largo de lo permitido. Longitud:";
		mensajeError.append(numeroCadena.c_str());
		throw ComunicacionException(mensajeError, true);
	}

	string longOk = formatearLongitud(numeroCadena);
	string mensaje = codigoMensaje;
	mensaje.append(longOk.c_str());
	if (mensaje.length() != (CANT_BYTES_PRIMER_MENSAJE - 1)){
		string mensajeError = "Error al formar el mensaje. Mensaje:";
		mensajeError.append(mensaje.c_str());
		throw ComunicacionException(mensajeError, true);
	}

	string finCadena = "\0";
	mensaje.append(finCadena.c_str());

	return mensaje;
}

bool ProtocoloServidor::enviarMensaje(int sockfd, string & codigoMensaje,
		string & mensaje){
	try {
		long longitud = mensaje.length();
		string primerMensaje = armarPrimerMensaje(codigoMensaje, longitud);
		if (!Protocolo::sendAll(sockfd, primerMensaje)){
			string mensajeError = "Error al enviar el primer mensaje con código:";
			mensajeError.append(codigoMensaje.c_str());
			throw ComunicacionException(mensajeError, true);
		}

		if (longitud != 0){
			if (!Protocolo::sendAll(sockfd, mensaje)){
				string mensajeError = "Error al enviar el segundo mensaje para código de mensaje:";
				mensajeError.append(codigoMensaje.c_str());
				throw ComunicacionException(mensajeError, true);
			}
		}

	} catch (ComunicacionException & e) {
		cerr << e.error() << std::endl;
		return false;
	}

	return true;
}

/*
 * Recibe la opcion seleccionada por el usuario,
 * 			- si crea partida (mensaje=1)
 * 			- se une a una existente (mensaje=0)
 *
 * @ param sockfdCliente
 * 		Descriptor del socket del que se va a leer (cliente = jugador).
 *
 * @ return
 * 		Mensaje (1 o 0).
 */
string ProtocoloServidor::recv_opcionSeleccionadaInicial(int sockfdCliente){
	string mensaje = "";
	string codigoMensaje = "";
	if (!Protocolo::recvAll(sockfdCliente, mensaje, codigoMensaje)){
		throw (ComunicacionException(Protocolo::mensajeErrorMensajeInicial(sockfdCliente), true));
	}

	if (codigoMensaje.compare((string(CP)).c_str()) != 0){
		throw ComunicacionException(Protocolo::mensajeErrorCodigo(codigoMensaje, sockfdCliente), false);
	}

	return mensaje;
}

/*
 * Se envia las campanias existentes en el juego.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 * @ param campanias
 * 		Campanias dentro del juego.
 *
 * @ mensajeEnviado
 * 		<Id de la campania>\t<Nombre de la campania>\t<Imagen>|...|<Id de la
 * 		campania>\t<Nombre de la campania>\t<Imagen>
 * TODO TODAVIA NO SE ENVIA LA IMAGEN EN ESTE MENSAJE
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_campaniasExistentes(int sockfdCliente,
		const vector<Campania *> & campanias){
	//Se va a enviar: id de la campania, nombre e imagen. Separados por \t
	string mensaje = "";
	std::size_t i;
	for (i = 0; i < campanias.size(); i++){
		Campania * campania = campanias[i];

		//Id
		string numeroCadena = Utils::pasarLongACadena(campania->getId());
		mensaje.append(numeroCadena.c_str());
		mensaje.append((string(SEPARADOR_DATOS_INTERNO)).c_str()); //Separador

		//Nombre
		mensaje.append(campania->getNombre().c_str());
		mensaje.append((string(SEPARADOR_DATOS_INTERNO)).c_str()); //Separador

		//imagen
		mensaje.append(campania->getImagen().c_str());
		mensaje.append((string(SEPARADOR_DATOS_INTERNO)).c_str()); //Separador

		//Separador de campania
		mensaje.append((string(SEPARADOR_DATOS)).c_str());
	}

	//Le saco el ultimo separador
	mensaje = mensaje.substr(0, mensaje.length() - 1);

	//Agrego fin de cadena
	string finCadena = "\0";
	mensaje.append(finCadena.c_str());

	string codigoMensaje = CE;
	return enviarMensaje(sockfdCliente, codigoMensaje, mensaje);
}

/*
 * Recibe la campania seleccionada y el nombre de la partida que desea
 * crear dentro de dicha campania.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket del que se va a leer (cliente = jugador).
 *
 * @ return
 * 		Mensaje:
 * 		<id de la campania seleccionada>|<nombre nueva partida>
 */
string ProtocoloServidor::recv_campaniaSeleccionadaYnombrePartida
		(int sockfdCliente){
	string mensaje = "";
	string codigoMensaje = "";
	if (!Protocolo::recvAll(sockfdCliente, mensaje, codigoMensaje)){
		throw (ComunicacionException(Protocolo::mensajeErrorMensajeInicial(sockfdCliente), true));
	}

	if (codigoMensaje.compare((string(CN)).c_str()) != 0){
		throw ComunicacionException(Protocolo::mensajeErrorCodigo(codigoMensaje, sockfdCliente), false);
	}

	return mensaje;
}

/*
 * Se envian las partidas todavia no comenzadas que existen.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 * @ param partidasNoComenzadas
 * 		Partidas todavia no comenzadas, informadas por Campania.
 *
 * @ mensajeEnviado
 * 		<Id partida>\t<Nombre partida>\t<Id campania>\t<Nombre
 * 		campania>\t<Imagen>|...|<Id partida>\t<Nombre partida>\t<Id
 * 		campania>\t<Nombre campania>\t<Imagen>
 * TODO TODAVIA NO SE ENVIA IMAGEN
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_partidasExistentesNoComenzadas(int sockfdCliente,
		map < Campania *, vector < Partida * > > & partidasNoComenzadas){
	//Se va a enviar: id de la partida, nombre partida, id campania, nombre campania e imagen campania. Separados por \t
	string mensaje = "";
	map<Campania *, vector<Partida *> >::const_iterator
		mit(partidasNoComenzadas.begin()), mend(partidasNoComenzadas.end());

	for (; mit != mend; ++mit){
		Campania * campania = mit->first;
		vector<Partida *> partidas = mit->second;
		std::size_t i;
		for (i = 0; i < partidas.size(); i++){
			Partida * partida = partidas[i];

			//Id partida
			string numeroCadena = Utils::pasarLongACadena(partida->getId());
			mensaje.append(numeroCadena.c_str());
			mensaje.append((string(SEPARADOR_DATOS_INTERNO)).c_str()); //Separador

			//Nombre partida
			string aux = partida->getNombre();
			mensaje.append(partida->getNombre().c_str());
			mensaje.append((string(SEPARADOR_DATOS_INTERNO)).c_str()); //Separador

			//Id campania
			numeroCadena = Utils::pasarLongACadena(campania->getId());
			mensaje.append(numeroCadena.c_str());
			mensaje.append((string(SEPARADOR_DATOS_INTERNO)).c_str()); //Separador

			//Nombre campania
			mensaje.append(campania->getNombre().c_str());
			mensaje.append((string(SEPARADOR_DATOS_INTERNO)).c_str()); //Separador

			// nombre de la imagen
			mensaje.append(partida->getImageFileName().c_str());
			mensaje.append((string(SEPARADOR_DATOS_INTERNO)).c_str()); //Separador

			//Separador de general
			mensaje.append((string(SEPARADOR_DATOS)).c_str());
		}
	}

	//Le saco el ultimo separador
	mensaje = mensaje.substr(0, mensaje.length() - 1);

	//Agrego fin de cadena
	string finCadena = "\0";
	mensaje.append(finCadena.c_str());

	string codigoMensaje = PE;
	return enviarMensaje(sockfdCliente, codigoMensaje, mensaje);
}

/*
 * Recibe la partida seleccionada a la cual se va a asociar el jugador.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket del que se va a leer (cliente = jugador).
 *
 * @ return
 * 		Mensaje:
 * 		<id de la partida seleccionada>
 */
int ProtocoloServidor::recv_partidaSeleccionada(int sockfdCliente){
	string mensaje = "";
	string codigoMensaje = "";
	if (!Protocolo::recvAll(sockfdCliente, mensaje, codigoMensaje)){
		throw (ComunicacionException(Protocolo::mensajeErrorMensajeInicial(sockfdCliente), true));
	}

	if (codigoMensaje.compare((string(PS)).c_str()) != 0){
		throw ComunicacionException(Protocolo::mensajeErrorCodigo(codigoMensaje, sockfdCliente), false);
	}

	return atoi(mensaje.c_str());
}

/*
 * Se informa que la partida esta en condiciones de ser comenzada:
 * tiene los jugadores minimos requeridos para poder comenzar.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 * @ param partida
 * 		Partida en condiciones de ser iniciada.
 *
 * @ mensajeEnviado
 * 		<Id partida>|<Nombre partida>
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_partidaListaParaComenzar(int sockfdCliente,
		Partida & partida){
	string mensaje = "";

	//Id partida
	string numeroCadena = Utils::pasarLongACadena(partida.getId());
	mensaje.append(numeroCadena.c_str());
	mensaje.append((string(SEPARADOR_DATOS)).c_str()); //Separador

	//Nombre partida
	//mensaje.append(partida.getNombre().c_str());

	//Agrego fin de cadena
	string finCadena = "\0";
	mensaje.append(finCadena.c_str());

	string codigoMensaje = PC;
	return enviarMensaje(sockfdCliente, codigoMensaje, mensaje);
}

/*
 * Recibe la decision de iniciar o no una partida.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket del que se va a leer (cliente = jugador).
 *
 * @ return
 * 		Pueden venir uno de los siguientes mensajes:
 * 		1|<id de la parida a comenzar>
 * 		0
 *
 * 		1: se quiere comenzar la partida
 * 		0: no se quiere comenzar la partida todavia
 */
string ProtocoloServidor::recv_comenzarPartida(int sockfdCliente){
	string mensaje = "";
	string codigoMensaje = "";
	if (!Protocolo::recvAll(sockfdCliente, mensaje, codigoMensaje)){
		throw (ComunicacionException(Protocolo::mensajeErrorMensajeInicial(sockfdCliente), true));
	}

	if (codigoMensaje.compare((string(CO)).c_str()) != 0){
		throw ComunicacionException(Protocolo::mensajeErrorCodigo(codigoMensaje, sockfdCliente), false);
	}

	return mensaje;
}

/*
 * Se informa que la partida fue iniciada.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 * @ param partida
 * 		Partida iniciada.
 *
 * @ mensajeEnviado
 * 		<Id partida>|<Nombre partida>
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_partidaIniciada(int sockfdCliente,
		Partida & partida){
	string mensaje = "";

	//Id partida
	string numeroCadena = Utils::pasarLongACadena(partida.getId());
	mensaje.append(numeroCadena.c_str());
	mensaje.append((string(SEPARADOR_DATOS)).c_str()); //Separador

	//Nombre partida
	mensaje.append(partida.getNombre().c_str());

	//Agrego fin de cadena
	string finCadena = "\0";
	mensaje.append(finCadena.c_str());

	string codigoMensaje = PI;
	return enviarMensaje(sockfdCliente, codigoMensaje, mensaje);
}

/*
 * Se informan las dimensiones que posee el escenario sobre
 * el cual se va a desarrollar la partida.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 * @ param cantidadFilas
 * 		Cantidad total de filas.
 * @ param cantidadColumnas
 * 		Cantidad total de columnas.
 *
 * @ mensajeEnviado
 * 		<Cantidad filas>|<Cantidad columnas>
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_dimensionEscenario(int sockfdCliente,
		long cantidadFilas, long cantidadColumnas){
	string mensaje = "";

	//Cantidad de filas totales
	string numeroCadena = Utils::pasarLongACadena(cantidadFilas);
	mensaje.append(numeroCadena.c_str());
	mensaje.append((string(SEPARADOR_DATOS)).c_str()); //Separador

	//Cantidad de columnas totales
	numeroCadena = Utils::pasarLongACadena(cantidadColumnas);
	mensaje.append(numeroCadena.c_str());

	//Agrego fin de cadena
	string finCadena = "\0";
	mensaje.append(finCadena.c_str());

	string codigoMensaje = DE;
	return enviarMensaje(sockfdCliente, codigoMensaje, mensaje);
}

/*
 * Recibe las coordenadas del escenario que le interesa al jugador.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket del que se va a leer (cliente = jugador).
 *
 * @ return
 * 		Mensaje:
 * 		<Nro Fila Desde>|<Nro Fila Hasta>|<Nro Columna Desde>|<Nro Columna
 * 		Hasta>
 */
string ProtocoloServidor::recv_coordenadasEscenarioInteresa
		(int sockfdCliente){
	string mensaje = "";
	string codigoMensaje = "";
	if (!Protocolo::recvAll(sockfdCliente, mensaje, codigoMensaje)){
		throw (ComunicacionException(Protocolo::mensajeErrorMensajeInicial(sockfdCliente), true));
	}

	if (codigoMensaje.compare((string(EI)).c_str()) != 0){
		throw ComunicacionException(Protocolo::mensajeErrorCodigo(codigoMensaje, sockfdCliente), false);
	}

	return mensaje;
}

/*
 * Se envia la parte del escenario que tiene interes en mostrar el cliente.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 * @ param tilesInteres
 * 		Tiles del escenario.
 * @ param cantFilas
 * 		Cantidad de filas de la parte del escenario a informar.
 * @ param cantColumnas
 * 		Cantidad de columnas de la parte del escenario a informar.
 *
 * @ mensajeEnviado
 * 		<Contenido celda M>|<Contenido celda M+1>|...|<Contenido celda N>
 * 		Se informa cada celda de la matriz, recorrida esta de arriba hacia
 * 		abajo y de izquierda a derecha.
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_escenarioInteresJugador(int sockfdCliente,
		vector<int> & tilesInteres, unsigned long cantFilas, unsigned long cantColumnas){
	string mensaje = "";
	std::size_t i; //Fila
	std::size_t j; //Columna
	for (i = 0; i < cantFilas; i++){
		for (j = 0; j < cantColumnas; j++){
			long indice = j + i*cantColumnas;
			long numero = tilesInteres[indice];
			string numeroCadena = Utils::pasarLongACadena(numero);
			mensaje.append(numeroCadena.c_str());
			mensaje.append((string(SEPARADOR_DATOS)).c_str()); //Separador
		}
	}

	//Le saco el ultimo separador
	mensaje = mensaje.substr(0, mensaje.length() - 1);

	//Agrego fin de cadena
	string finCadena = "\0";
	mensaje.append(finCadena.c_str());

	string codigoMensaje = EJ;
	return enviarMensaje(sockfdCliente, codigoMensaje, mensaje);
}

/*
 * Se envia informacion del puntaje de un jugador.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 * @ param player
 * 		Jugador con puntaje.
 *
 * @ mensajeEnviado
 *    <Id del jugador>|<Nombre del jugador>|<Puntaje>
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_puntajeYjugador(int sockfdCliente,
		Player & player){
	//Id del jugador, su nombre y su puntaje
	string mensaje = "";

	//Id del jugador
	string numeroCadena = Utils::pasarLongACadena(player.getId());
	mensaje.append(numeroCadena.c_str());
	mensaje.append((string(SEPARADOR_DATOS)).c_str()); //Separador

	//Nombre del jugador
	mensaje.append(player.getNombre());
	mensaje.append((string(SEPARADOR_DATOS)).c_str()); //Separador

	//Puntaje del jugador
	//numeroCadena = Utils::pasarLongACadena(player.getPuntaje());
	//mensaje.append(numeroCadena.c_str());

	//Agrego fin de cadena
	string finCadena = "\0";
	mensaje.append(finCadena.c_str());

	string codigoMensaje = JP;
	return enviarMensaje(sockfdCliente, codigoMensaje, mensaje);
}

/*
 * Se informa el fin de un partida
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 * @ param partida
 * 		Partida finalizada.
 *
 * @ mensajeEnviado
 *    <Id de la partida>|<Nombre de la partida>
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_finPartida(int sockfdCliente, Partida & partida){
	//Id de la partida y su nombre
	string mensaje = "";

	//Id de la partida
	string numeroCadena = Utils::pasarLongACadena(partida.getId());
	mensaje.append(numeroCadena.c_str());
	mensaje.append((string(SEPARADOR_DATOS)).c_str()); //Separador

	//Nombre de la partida
	mensaje.append(partida.getNombre());

	//Agrego fin de cadena
	string finCadena = "\0";
	mensaje.append(finCadena.c_str());

	string codigoMensaje = FP;
	return enviarMensaje(sockfdCliente, codigoMensaje, mensaje);
}

/*
 * Se informa la explosion de una bomba.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_explosionBomba(int sockfdCliente){
	string codigoMensaje = EB;
	string mensaje = "";
	return enviarMensaje(sockfdCliente, codigoMensaje, mensaje);
}

/*
 * Se informa que un jugador fue destruido.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 * @ param player
 * 		Bomberman destruido.
 *
 * @ mensajeEnviado
 *      <id del bomberman>|<nombre>
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_bombermanDestruido(int sockfdCliente,
		Player & player){
	//Id del jugador y su nombre
	string mensaje = "";

	//Id del jugador
	string numeroCadena = Utils::pasarLongACadena(player.getId());
	mensaje.append(numeroCadena.c_str());
	mensaje.append((string(SEPARADOR_DATOS)).c_str()); //Separador

	//Nombre del jugador
	mensaje.append(player.getNombre());

	//Agrego fin de cadena
	string finCadena = "\0";
	mensaje.append(finCadena.c_str());

	string codigoMensaje = BD;
	return enviarMensaje(sockfdCliente, codigoMensaje, mensaje);
}

/*
 * Se informa que un zombie ha sido destruido.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_zombieDestruido(int sockfdCliente){
	string mensaje = "";
	string codigoMensaje = ZD;
	return enviarMensaje(sockfdCliente, codigoMensaje, mensaje);
}

/*
 * Se informa que una planta ha lanzado una bomba.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_bombaLanzadaPlanta(int sockfdCliente){
	string mensaje = "";
	string codigoMensaje = BP;
	return enviarMensaje(sockfdCliente, codigoMensaje, mensaje);
}

/*
 * Recibe la informacion de que han generado un bomba.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket del que se va a leer (cliente = jugador).
 *
 * @ return
 * 		Mensaje:
 * 		<Fila donde se genero bomba>|<Columna donde se genero bomba>
 */
string ProtocoloServidor::recv_bombaGeneradaBomberman(int sockfdCliente){
	string mensaje = "";
	string codigoMensaje = "";
	if (!Protocolo::recvAll(sockfdCliente, mensaje, codigoMensaje)){
		throw (ComunicacionException(Protocolo::mensajeErrorMensajeInicial(sockfdCliente), true));
	}

	if (codigoMensaje.compare((string(BB)).c_str()) != 0){
		throw ComunicacionException(Protocolo::mensajeErrorCodigo(codigoMensaje, sockfdCliente), false);
	}

	return mensaje;
}

/*
 * Se informa que un bomberman ha generado una bomba.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 *
 * @ mensajeEnviado
 *		<X donde se genero bomba>|<Y donde se genero bomba>
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_bombaGeneradaBomberman(int sockfdCliente,
		long fila, long columna){

	 string mensaje = "";

	 //Fila
	 string numeroCadena = Utils::pasarLongACadena(fila);
	 mensaje.append(numeroCadena.c_str());
	 mensaje.append((string(SEPARADOR_DATOS)).c_str()); //Separador

	 //Columna
	 numeroCadena = Utils::pasarLongACadena(columna);
	 mensaje.append(numeroCadena.c_str());

	 //Agrego fin de cadena
	 string finCadena = "\0";
	 mensaje.append(finCadena.c_str());

	 string codigoMensaje = BB;
	 return enviarMensaje(sockfdCliente, codigoMensaje, mensaje);
}

/*
 * Se informa que un nuevo bomberman se ha unido a la partida.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 * @ param partida
 * 		Partida a la que se ha unido el bomberman.
 *
 * @ mensajeEnviado
 * 		<Id partida>|<Nombre partida>
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_nuevoBomberman(int sockfdCliente, Partida & partida){
	//Id de la partida y su nombre
	string mensaje = "";

	//Id de la partida
	string numeroCadena = Utils::pasarLongACadena(partida.getId());
	mensaje.append(numeroCadena.c_str());
	mensaje.append((string(SEPARADOR_DATOS)).c_str()); //Separador

	//Nombre de la partida
	mensaje.append(partida.getNombre());

	//Agrego fin de cadena
	string finCadena = "\0";
	mensaje.append(finCadena.c_str());

	string codigoMensaje = NB;
	return enviarMensaje(sockfdCliente, codigoMensaje, mensaje);
}

/*
 * Recibe el movimiento del jugador.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket del que se va a leer (cliente = jugador).
 *
 * @ return
 * 		Mensaje:
 * 		<Alguno de los siguientes movimientos: UP, RIGHT, DOWN, LEFT>
 */
string ProtocoloServidor::recv_movimientoJugador(int sockfdCliente){
	string mensaje = "";
	string codigoMensaje = "";
	if (!Protocolo::recvAll(sockfdCliente, mensaje, codigoMensaje)){
		throw (ComunicacionException(Protocolo::mensajeErrorMensajeInicial(sockfdCliente), true));
	}

	if (codigoMensaje.compare((string(MO)).c_str()) != 0){
		throw ComunicacionException(Protocolo::mensajeErrorCodigo(codigoMensaje, sockfdCliente), false);
	}

	return mensaje;
}

/*
 * Recibe la solicitud de los cambios ocurridos.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket del que se va a leer (cliente = jugador).
 *
 * @ return
 * 		Mensaje
 */
string ProtocoloServidor::recv_requestForUpdates(int sockfdCliente){
	string mensaje = "";
	string codigoMensaje = "";
	if (!Protocolo::recvAll(sockfdCliente, mensaje, codigoMensaje)){
		throw (ComunicacionException(Protocolo::mensajeErrorMensajeInicial(sockfdCliente), true));
	}

	if (codigoMensaje.compare((string(RU)).c_str()) != 0){
		throw ComunicacionException(Protocolo::mensajeErrorCodigo(codigoMensaje, sockfdCliente), false);
	}

	return mensaje;
}

string ProtocoloServidor::recv_updates(int sockfdCliente){
	string mensaje = "";
	string codigoMensaje = "";
	if (!Protocolo::recvAll(sockfdCliente, mensaje, codigoMensaje)){
		throw (ComunicacionException(Protocolo::mensajeErrorMensajeInicial(sockfdCliente), true));
	}
	return mensaje;
}

/*
 * Se informan las updates del servidor, si las hubiera.
 *
 * @ param sockfdCliente
 * 		Descriptor del socket al que se le va a enviar datos
 * 		(cliente = jugador).
 * @ param updates
 * 		Mensaje con las actualizaciones (mensaje que se envia).
 *
 * @ return
 * 		True si pudo enviar el mensaje completamente. Caso contrario, false.
 */
bool ProtocoloServidor::send_requestForUpdates(int sockfdCliente,
		string updates){
	//Agrego fin de cadena
	string finCadena = "\0";
	updates.append(finCadena.c_str());

	string codigoMensaje = RU;
	return enviarMensaje(sockfdCliente, codigoMensaje, updates);
}

bool ProtocoloServidor::send_scenario(int sockfdCliente, string scenario){
	//Agrego fin de cadena
	string finCadena = "\0";
	scenario.append(finCadena.c_str());

	string codigoMensaje = RS;
	return enviarMensaje(sockfdCliente, codigoMensaje, scenario);
}
